/**
 * 网络剪切板 IndexedDB 存储工具
 */

const DB_NAME = 'ClipboardManager'
const DB_VERSION = 1
const CLIPBOARD_STORE = 'clipboards'
const ACCESS_HISTORY_STORE = 'accessHistory'

export interface ClipboardRecord {
  id: string
  shareId: string
  adminPassword?: string
  accessPassword?: string
  title?: string
  createdAt: number
  lastAccessAt: number
  isAdmin: boolean
}

export interface AccessHistory {
  id: string
  shareId: string
  accessedAt: number
}

class ClipboardStorage {
  private db: IDBDatabase | null = null

  async init(): Promise<void> {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open(DB_NAME, DB_VERSION)

      request.onerror = () => {
        console.error('IndexedDB 打开失败:', request.error)
        reject(request.error)
      }

      request.onsuccess = () => {
        this.db = request.result
        console.log('ClipboardStorage IndexedDB 初始化成功')
        resolve()
      }

      request.onupgradeneeded = (event) => {
        const db = (event.target as IDBOpenDBRequest).result
        
        // 创建剪切板存储
        if (!db.objectStoreNames.contains(CLIPBOARD_STORE)) {
          const store = db.createObjectStore(CLIPBOARD_STORE, { keyPath: 'id' })
          store.createIndex('shareId', 'shareId', { unique: true })
          store.createIndex('createdAt', 'createdAt', { unique: false })
        }

        // 创建访问历史存储
        if (!db.objectStoreNames.contains(ACCESS_HISTORY_STORE)) {
          const historyStore = db.createObjectStore(ACCESS_HISTORY_STORE, { keyPath: 'id' })
          historyStore.createIndex('shareId', 'shareId', { unique: false })
          historyStore.createIndex('accessedAt', 'accessedAt', { unique: false })
        }
      }
    })
  }

  // 保存剪切板记录
  async saveClipboard(record: Omit<ClipboardRecord, 'id'>): Promise<string> {
    if (!this.db) await this.init()

    return new Promise((resolve, reject) => {
      if (!this.db) {
        reject(new Error('数据库未初始化'))
        return
      }

      const transaction = this.db.transaction([CLIPBOARD_STORE], 'readwrite')
      const store = transaction.objectStore(CLIPBOARD_STORE)
      
      const id = `clipboard_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
      const data: ClipboardRecord = {
        ...record,
        id,
        lastAccessAt: Date.now()
      }

      const request = store.put(data)

      request.onsuccess = () => {
        console.log('剪切板记录已保存')
        resolve(id)
      }

      request.onerror = () => {
        console.error('保存剪切板记录失败:', request.error)
        reject(request.error)
      }
    })
  }

  // 更新剪切板记录
  async updateClipboard(id: string, updates: Partial<ClipboardRecord>): Promise<void> {
    if (!this.db) await this.init()

    return new Promise(async (resolve, reject) => {
      if (!this.db) {
        reject(new Error('数据库未初始化'))
        return
      }

      try {
        const existing = await this.getClipboardById(id)
        if (!existing) {
          reject(new Error('记录不存在'))
          return
        }

        const transaction = this.db.transaction([CLIPBOARD_STORE], 'readwrite')
        const store = transaction.objectStore(CLIPBOARD_STORE)
        
        const data: ClipboardRecord = {
          ...existing,
          ...updates,
          id,
          lastAccessAt: Date.now()
        }

        const request = store.put(data)

        request.onsuccess = () => {
          console.log('剪切板记录已更新')
          resolve()
        }

        request.onerror = () => {
          console.error('更新剪切板记录失败:', request.error)
          reject(request.error)
        }
      } catch (error) {
        reject(error)
      }
    })
  }

  // 根据ID获取剪切板记录
  async getClipboardById(id: string): Promise<ClipboardRecord | null> {
    if (!this.db) await this.init()

    return new Promise((resolve, reject) => {
      if (!this.db) {
        reject(new Error('数据库未初始化'))
        return
      }

      const transaction = this.db.transaction([CLIPBOARD_STORE], 'readonly')
      const store = transaction.objectStore(CLIPBOARD_STORE)
      const request = store.get(id)

      request.onsuccess = () => {
        resolve(request.result || null)
      }

      request.onerror = () => {
        console.error('获取剪切板记录失败:', request.error)
        reject(request.error)
      }
    })
  }

  // 根据shareId获取剪切板记录
  async getClipboardByShareId(shareId: string): Promise<ClipboardRecord | null> {
    if (!this.db) await this.init()

    return new Promise((resolve, reject) => {
      if (!this.db) {
        reject(new Error('数据库未初始化'))
        return
      }

      const transaction = this.db.transaction([CLIPBOARD_STORE], 'readonly')
      const store = transaction.objectStore(CLIPBOARD_STORE)
      const index = store.index('shareId')
      const request = index.get(shareId)

      request.onsuccess = () => {
        resolve(request.result || null)
      }

      request.onerror = () => {
        console.error('获取剪切板记录失败:', request.error)
        reject(request.error)
      }
    })
  }

  // 获取所有剪切板记录
  async getAllClipboards(): Promise<ClipboardRecord[]> {
    if (!this.db) await this.init()

    return new Promise((resolve, reject) => {
      if (!this.db) {
        reject(new Error('数据库未初始化'))
        return
      }

      const transaction = this.db.transaction([CLIPBOARD_STORE], 'readonly')
      const store = transaction.objectStore(CLIPBOARD_STORE)
      const request = store.getAll()

      request.onsuccess = () => {
        const results = request.result || []
        // 按最后访问时间排序
        results.sort((a, b) => b.lastAccessAt - a.lastAccessAt)
        resolve(results)
      }

      request.onerror = () => {
        console.error('获取所有剪切板记录失败:', request.error)
        reject(request.error)
      }
    })
  }

  // 删除剪切板记录
  async deleteClipboard(id: string): Promise<void> {
    if (!this.db) await this.init()

    return new Promise((resolve, reject) => {
      if (!this.db) {
        reject(new Error('数据库未初始化'))
        return
      }

      const transaction = this.db.transaction([CLIPBOARD_STORE], 'readwrite')
      const store = transaction.objectStore(CLIPBOARD_STORE)
      const request = store.delete(id)

      request.onsuccess = () => {
        console.log('剪切板记录已删除')
        resolve()
      }

      request.onerror = () => {
        console.error('删除剪切板记录失败:', request.error)
        reject(request.error)
      }
    })
  }

  // 保存访问历史
  async saveAccessHistory(shareId: string): Promise<void> {
    if (!this.db) await this.init()

    return new Promise((resolve, reject) => {
      if (!this.db) {
        reject(new Error('数据库未初始化'))
        return
      }

      const transaction = this.db.transaction([ACCESS_HISTORY_STORE], 'readwrite')
      const store = transaction.objectStore(ACCESS_HISTORY_STORE)
      
      const data: AccessHistory = {
        id: `history_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
        shareId,
        accessedAt: Date.now()
      }

      const request = store.add(data)

      request.onsuccess = () => {
        console.log('访问历史已记录')
        resolve()
      }

      request.onerror = () => {
        console.error('记录访问历史失败:', request.error)
        reject(request.error)
      }
    })
  }

  // 获取最近访问的分享ID列表
  async getRecentShareIds(limit: number = 10): Promise<string[]> {
    if (!this.db) await this.init()

    return new Promise((resolve, reject) => {
      if (!this.db) {
        reject(new Error('数据库未初始化'))
        return
      }

      const transaction = this.db.transaction([ACCESS_HISTORY_STORE], 'readonly')
      const store = transaction.objectStore(ACCESS_HISTORY_STORE)
      const index = store.index('accessedAt')
      const request = index.openCursor(null, 'prev')

      const shareIds: string[] = []
      const uniqueShareIds = new Set<string>()

      request.onsuccess = () => {
        const cursor = request.result
        if (cursor && shareIds.length < limit) {
          const record = cursor.value as AccessHistory
          if (!uniqueShareIds.has(record.shareId)) {
            uniqueShareIds.add(record.shareId)
            shareIds.push(record.shareId)
          }
          cursor.continue()
        } else {
          resolve(shareIds)
        }
      }

      request.onerror = () => {
        console.error('获取访问历史失败:', request.error)
        reject(request.error)
      }
    })
  }

  // 清除所有数据
  async clearAll(): Promise<void> {
    if (!this.db) await this.init()

    return new Promise((resolve, reject) => {
      if (!this.db) {
        reject(new Error('数据库未初始化'))
        return
      }

      const transaction = this.db.transaction([CLIPBOARD_STORE, ACCESS_HISTORY_STORE], 'readwrite')
      
      const clipboardClear = transaction.objectStore(CLIPBOARD_STORE).clear()
      const historyClear = transaction.objectStore(ACCESS_HISTORY_STORE).clear()

      transaction.oncomplete = () => {
        console.log('所有数据已清除')
        resolve()
      }

      transaction.onerror = () => {
        console.error('清除数据失败:', transaction.error)
        reject(transaction.error)
      }
    })
  }

  // 关闭数据库连接
  close(): void {
    if (this.db) {
      this.db.close()
      this.db = null
      console.log('ClipboardStorage 数据库连接已关闭')
    }
  }
}

// 创建单例实例
export const clipboardStorage = new ClipboardStorage()

export default clipboardStorage